import Fmp4 from './Fmp4.js'
import G711 from './G711.js'
import G726 from './G726.js'
import AACDecoder from './AACDecoder.js'
import Adpcm from './Adpcm.js'
import AudioCodec from './AudioCodec.js'
import PCMPlayer from './PCMPlayer.js'
import Result from './Result.js'
import Rtp from './Rtp.js'
import Std from './Std.js'

export default class RTPMediaPlayer {
  /**
   * defaults为整个插件的默认参数
   * 'video/webm; codecs=“vorbis,vp8”’ webm类型
   * 'video/mp4; codecs=“avc1.42E01E,mp4a.40.2”’ MP4类型
   * 'video/mp2t; codecs=“avc1.42E01E,mp4a.40.2”’ ts类型
   * 'video/mp4; codecs="avc1.420028"'
   * @type {{}}
   */
  constructor(opt) {

    this.defaults = {
      /**
       * 回调事件
       */
      // 播放
      onPlaying: null,
      // 暂停
      onPause: null,
      // 结束
      onEnded: null,
      // 错误
      onError: null,
      // 连接超时
      timeoutFun: null,
      // socket关闭
      socketCloseFun: null,
      // 视频打开成功事件
      openVideoSuccess: null,
      // 视频打开失败事件
      openVideoFail: null,
      // 音频打开成功事件
      openAudioSuccess: null,
      // 音频打开失败事件
      openAudioFail: null,
      // 缺少设备回调函数
      onDevicePresentFunc: null,

      mimeCodec: 'video/mp4; codecs="avc1.420028"',
      url: '',
      domId: '',
      /**
       * 音频编码类型
       * 8 g726
       * 26 adpcm
       * 1 g721
       */
      codingType: null,
      // 外部提供的数据
      data: null,
      // 视频播放类型
      // 实时 REAL_TIME
      // 回放 TRACK_BACK
      playType: 'REAL_TIME',
      /**
       * 操作类型
       * BOTH_WAY 对讲，UP_WAY 监听，DOWN_WAY 广播
       * 默认对讲
       */
      type: 'BOTH_WAY',

      audioEnabled: false,
      videoEnabled: true,
      recordEnabled: false,
    };
    this.streamInfo = {
      target:1,
      ip:'',
      port:0,
      state:-1,
      timestampStart:0,
      timestampEnd:0,
      message:'',
      sendBytes:0,
      recvBytes:0,
      simNumber:'',
      channel:0,
      uuid:'',
    };


    this._addAssign();

    this.options = Object.assign({}, this.defaults, opt);



    /**
     *  pendingRemoveRanges为source缓存数据清空定时器
     */
    this.pendingRemoveRanges = null;
    /**
     * this.mediaElement为video标签
     */
    this.mediaElement = null;
    /**
     * this.mediaSource为MSE sourceBuffer
     */
    this.mediaSource = null;
    this.websocket = null;
    this.sourceBuffer = null;

    /**
     * 初始化h264转fmp4方法类
     */
    this.fmp4 = null;

    /**
     * socket连接成功后，是否有消息接收
     */
    this.messageState = false;

    /**
     * 监听超时定时器
     */
    this.timeOutMonitoring = null;

    /**
     * 当前页面是否聚焦
     */
    this.pageFocus = true;

    /**
     * 视频是否已经播放
     */
    this.isVideoPlay = false;

    /**
     * socket是否被关闭
     */
    this.socketState = true;

    /**
     * create url
     */
    this.mediaSourceObjectURL = null;

    /**
     * 心跳代码
     */
    this.heartbeat = null;

    this.startTime = 0;

    /**
     * 视频声音开启状态
     */
    this.audioEnabled = this.options.audioEnabled;
    this.videoEnabled = this.options.videoEnabled;
    this.recordEnabled = this.options.recordEnabled;

    this.rtp = new Rtp();

    /**
     * 缓存清理参数
     */
    this.clearFlag = 0;
    this.clearTime = 0;

    /**
     * 空闲超时
     */
    this.freeTimeout = null;

    /**
     * 超时重连计数
     */
    this.timeoutNumber = 0;

    this.isPFrame = 0;

    this.videoCurrentTime = 0;

    this.audioCodec = null;
    this.pcmPlayer = null;
    this.audioRecorder = null;
    this.recvPackageTimeArr = new Array();
    this.payloadTypeAudio = -1;
    this.firstAudioPlayData = true;
    this.firstAudioRecordeData = true;

    this._initStreamInfo();

    this._websocketInit();

    if (this.videoEnabled){
      this._createMediaSource();
    }
    this.audioOpt = {
      onDecodeFunc : this._onDecodeDataAudio.bind(this),
      onEncodeFunc : this._onEncodeDataAudio.bind(this),
    };
    if (this.audioEnabled) {
      this.pcmPlayer = new PCMPlayer(1, 8000);
      this.audioCodec = new AudioCodec(this.audioOpt);
    }
    this.recordOpt = {
      onDataFunc : this._onRecordDataAudio.bind(this),
      onDevicePresentFunc : this._onDevicePresent.bind(this),
    };
    if (this.recordEnabled){
      this.audioRecorder = new AudioRecorder(this.recordOpt);
    }
  }

  /**
   * 初始化当前流信息
   * @private
   */
  _initStreamInfo(){
    try {
      let startIndex = this.options.url.indexOf('//');
      let portStartIndex = this.options.url.indexOf(':',startIndex);
      let lastIndex = this.options.url.lastIndexOf('/');
      this.streamInfo.ip = this.options.url.substr(startIndex+2, portStartIndex-startIndex-2)
      this.streamInfo.port = parseInt(this.options.url.substr(portStartIndex+1, lastIndex-portStartIndex-1));

      if (this.options.data){
        this.streamInfo.simNumber = this.options.data.mobile;
        this.streamInfo.channel = parseInt(this.options.data.channelNum);
        this.streamInfo.uuid = this.options.data.vehicleId;
      }
    }
    catch(err){
      console.error(err);
    }
  }

  /**
   * 判断浏览器是否支持Object.assign方法
   * 不支持就进行手动添加
   */
  _addAssign () {
    if (typeof Object.assign != 'function') {
      Object.defineProperty(Object, "assign", {
        value: function assign(target, varArgs) {
          'use strict';
          if (target == null) {
            throw new TypeError('Cannot convert undefined or null to object');
          }

          var to = Object(target);

          for (var index = 1; index < arguments.length; index++) {
            var nextSource = arguments[index];

            if (nextSource != null) {
              for (var nextKey in nextSource) {
                if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                  to[nextKey] = nextSource[nextKey];
                }
              }
            }
          }
          return to;
        },
        writable: true,
        configurable: true
      });
    }
  }


  /**
   * 判断浏览器是否支持MediaSource和指定要解码播放的视频文件编码和类型
   * @returns {boolean|*}
   */
  _isMseSupport () {
    return 'MediaSource' in window && MediaSource.isTypeSupported(this.options.mimeCodec);
  }

  /**
   * 初始化MediaSource
   */
  _createMediaSource () {
    if (!this._isMseSupport()) {
      throw new Error('浏览器不支持MediaSource或指定的编码类型');
    }
    if (!this.options.domId){
      throw new Error('domId不能为空');
    }
    this.mediaSource = new window.MediaSource();
    /**
     * 如果获取的video状态为未播放状态就替换节点
     */

    let newVideo = document.createElement('video');
    this.mediaElement = document.getElementById(this.options.domId);
    this.mediaElement.setAttribute('data-channel-up', 'true');

    this.mediaSourceObjectURL = window.URL.createObjectURL(this.mediaSource);
    this.mediaElement.src = this.mediaSourceObjectURL;

    /**
     * 给video标签绑定一系列监听事件
     * playing 在媒体开始播放时触发
     * pause 播放暂停时触发
     * ended 播放结束时触发
     * error 发生错误时触发
     */
    this.mediaElement.onplaying = this._onPlaying.bind(this);
    this.mediaElement.onpause = this._onPause.bind(this);
    this.mediaElement.onended= this._onEnded.bind(this);
    this.mediaElement.onerror = this._onError.bind(this);

    /**
     * mediaSource的一系列监听事件
     */
    this.mediaSource.onsourceopen = this._onMediaSourceOpen.bind(this);
    this.mediaSource.onsourceended = this._onMediaSourceEnded.bind(this);
    this.mediaSource.onerror = this._onUpdateError.bind(this);

    /**
     * 判断浏览器类型，调用视频play方法
     */
    this._mediaElementPlay();
  }

  /**
   * 目前是获取是火狐浏览器就进行播放
   */
  _mediaElementPlay() {
    // if (navigator.userAgent.indexOf("Firefox") > 0)
    this.mediaElement.play();
  }

  /**
   * mediaElement-视频开始播放时
   */
  _onPlaying () {
    // console.log('onPlaying');
    if (this.pageFocus) {
      if (this.options.onPlaying && !this.isVideoPlay) {
        this.isVideoPlay = true;
        this.options.onPlaying(this.options.data, this);
      }
    } else {
      this.pageFocus = true;
    }
  }

  /**
   * mediaElement-视频播放暂停时
   */
 _onPause () {
    if (this.pageFocus) {
      if (this.options.onPause) {
        this.options.onPause();
      }
      // 播放暂停时，保持连接，后台继续获取并解码数据
      // this.websocket.close();
    }
  }

  /**
   * mediaElement-视频播放结束时
   */
 _onEnded () {
    console.log('视频播放结束');
    if (this.options.onEnded) {
      this.options.onEnded();
    }
    this.closeSocket('End of play!');
  }

  /**
   * mediaElement-视频播放发生错误时
   */
  _onError (err) {
    const videoElement = err.target;
    console.log('code: ' + videoElement.error.code, ', message: ' + videoElement.error.message);

    this.closeSocket('Codec error， code: ' + videoElement.error.code, ', message: ' + videoElement.error.message)
    if (this.options.onErrorFun) {
      this.options.onErrorFun(4)
    }
  }

  /**
   * mediaSource监听打开事件
   */
  _onMediaSourceOpen () {
    console.log('onMediaSourceOpen');
    if (!this.sourceBuffer){
      this.sourceBuffer = this.mediaSource.addSourceBuffer(this.options.mimeCodec);
      this.sourceBuffer.onerror = this._onSourceBufferError.bind(this);
    }
  }
  /**
   * mediaSource监听结束事件
   */
  _onMediaSourceEnded () {
    console.log('MediaSource onSourceEnded');
  }

  /**
   * mediaSource监听错误事件
   */
  _onUpdateError (error) {
    console.warn(error);
  }

  /**
   * source监听一段chunk播放完毕事件
   */

  /**
   * 组装buffered并内存释放
   * 1分钟清一次视频缓存
   */
  _doCleanupSourceBuffer () {
    const that = this;
    this.pendingRemoveRanges = setInterval(function () {
      if (that.sourceBuffer) {
        if(!this.sourceBuffer.updating) {
          let buffered = that.sourceBuffer.buffered;
          if (buffered.length > 0) {
            let start = buffered.start(0);
            let end = buffered.end(0);
            try {
              that.sourceBuffer.remove(start, end - 10);
            } catch (err) {
              console.warn(err.message);
            }
          }
        }
      }
    }, 40000);
  }

  /**
   * source监听错误事件
   */
  _onSourceBufferError (error) {
    console.warn(error);
  }


  /**
   * 监听页面是否失去焦点
   * 失去焦点后，页面播放视频暂停
   * 获取焦点后，视频跳转到最新
   */
  _visibilitychangeFun () {
    const isHidden = document.hidden;
    if (!isHidden) {
      this._videoUpdateTime();
    } else {
      this.pageFocus = false;
    }
  }

  /**
   * 测试
   * 直接添加视频片段segment
   */
  _doAppendSegments (segment) {
    if (this.sourceBuffer && !this.sourceBuffer.updating && this.socketState && this.messageState) {
      this.sourceBuffer.appendBuffer(segment);
    }
  }

  /**
   * websocket 链接
   */
  _websocketInit() {
    /**
     * 判断是否支持websocket且url地址不为空
     */
    if (this.websocket == null || this.websocket.readyState == 3){
      console.log('websocketInit');
      if ('WebSocket' in window && this.options.url !== '') {
        this.websocket = new WebSocket(this.options.url);
        /**
         * 设置接收的二进制数据格式
         * @type {string}
         */
        this.websocket.binaryType = 'arraybuffer';

        this.websocket.onopen = this._socketOpen.bind(this);
        this.websocket.onmessage = this._socketMessage.bind(this);
        this.websocket.onerror = this._socketError.bind(this);
        this.websocket.onclose = this._socketClose.bind(this);
      } else {
        throw new Error('浏览器不支持websocket或url为空');
      }
    }
  }

  _visibilityEvent () {
    RTPMediaPlayer.arr.forEach(function(ele){
      ele.call();
    });
  }
  /**
   * websocket成功建立的回调函数
   */
  _socketOpen () {
    console.log('socketopen', new Date().getTime())
    this.streamInfo.timestampStart = new Date().getTime();
    this.streamInfo.state = '0';
    // this._doCleanupSourceBuffer();
    this._monitoringMessage();
    document.onvisibilitychange = this._visibilityEvent;
    RTPMediaPlayer.arr.push(this._visibilitychangeFun.bind(this))
    this.fmp4 = new Fmp4(10 * 1024 * 1024);
    /**
     * 发送心跳
     * @type {number}
     */
    var that = this;
    this.heartbeat = setInterval(function () {
      let senddata = '0';
      if (this.sourceBuffer && this.mediaElement && this.sourceBuffer.buffered.length>0){
        let endTime = this.sourceBuffer.buffered.end(0);
        let startTime = this.sourceBuffer.buffered.start(0);
        let currentTime = this.mediaElement.currentTime;
        // console.log('currentTime='+currentTime+',startTime='+startTime+',endTime='+endTime);
        if (endTime-currentTime>600){
          // 未播放的缓存超过10分钟通知后台暂停
          if (this.options.playType == 'TRACK_BACK'){
            senddata = '1';
          }
        }
      }
      if (that.websocket.readyState == 1){
        this.streamInfo.sendBytes += senddata.length;
        that.websocket.send(senddata);
      } else {
        console.error('Heartbeat error!');
      }
    }.bind(this), 5000);
  }
  /**
   * websocket发生错误的回调函数
   */
  _socketError (error) {
    console.warn(error);
    this.streamInfo.message = 'socket error:'+error;
    if (this.options.onErrorFun) {
      this.options.onErrorFun(1)
    }
  }

  /**
   * websocket关闭的回调函数
   */
  _socketClose () {
    console.log('socketClose', new Date().getTime())
    if (this.websocket) {
      this.streamInfo.timestampEnd = new Date().getTime();
      this.streamInfo.state = '2';
      this.socketState = false;
      clearTimeout(this.timeOutMonitoring);
      if (this.options.socketCloseFun) {
        this.options.socketCloseFun(this.options.data);
      }
      clearInterval(this.pendingRemoveRanges);
      this.pendingRemoveRanges = null;
      this.destroy();
    }
  }
  /**
   * websocket接收消息的回调函数
   */
  _socketMessage (event) {
    // console.log('socketMessage', event)
    if (!this.messageState) {
      this.messageState = true;
    }
    /**
     * 对socket发送过来的数据进行处理转换成fmp4
     * 然后调用MSE方法塞进video，进行视频播放
     *
     */
    /**
     * 解析rtp数据，获得H264数据
     *
     */
    this.streamInfo.recvBytes += event.data.byteLength;
    let rtpFrame = this.rtp.parse(event.data);
    let payloadType = this.rtp.getPayloadType();
    if(rtpFrame.errorCode === Result.ErrorCode.SUCCESS) {
      this.streamInfo.state = '1';
      /**
       * 判断是否是视频数据
       */
      // rtpFrame.duration = rtpFrame.duration == 0 ? 40 : rtpFrame.duration;
      if(rtpFrame.media_type === Result.MediaType.H264)
       {
        if (!this.videoEnabled || !this.sourceBuffer){
          return;
        }
        // console.log('video time='+rtpFrame.time+',duration='+rtpFrame.duration);
        /**
         * 清除视频缓存
         * @type {number}
         */
        if (rtpFrame.frame_type === Result.FrameType.KEY) {
          ++this.clearFlag;
        }

        if (this.options.remoteMode === 2 || this.options.remoteMode === 3) {
          this.isPFrame = 0;
        } else {
          this.isPFrame = 1;
        }
        rtpFrame.duration = this.startTime === 0 ? 0 : (rtpFrame.duration > 0 ?
            rtpFrame.duration : rtpFrame.time - this.startTime);
        if(this.isPFrame === 1)
        {
          rtpFrame.duration = (rtpFrame.duration > 0 && rtpFrame.duration < 2000) ?
              rtpFrame.duration : ((this.startTime === 0 && rtpFrame.duration === 0) ? 0 : 500);
        }

        if(this.sourceBuffer && !this.sourceBuffer.updating) {
          /**
           * 清除视频缓存
           * @type {number}
           */
          if (this.options.playType === 'REAL_TIME') {
            if (this.clearFlag > 10) {
              if(this.clearTime !== 0) {
                this.sourceBuffer.remove(0, this.clearTime);
                if(this.mediaElement.currentTime<this.clearTime) {
                  this.mediaElement.currentTime = this.clearTime;
                }
              }
              this.clearTime = this.fmp4.getLastIFrameTime() / 1000;
              this.clearFlag = 0;
            }
          }
          if (this.sourceBuffer && this.mediaElement && this.sourceBuffer.buffered.length>0){
            let startTime = this.sourceBuffer.buffered.start(0);
            let currentTime = this.mediaElement.currentTime;
            if (currentTime - startTime > 60) {
              // 暂时只保留1分钟已播放的缓存
              this.sourceBuffer.remove(0, currentTime-60);
            }
          }
        }

        if(this.sourceBuffer && !this.sourceBuffer.updating) {
          /**
           * 将H264数据，封装为Fmp4数据，frameDuration为延迟，可通过rtpFrame.time计算
           */
          let fmp4Frame = this.fmp4.makeVideoFrame(rtpFrame, rtpFrame.duration);
          if(fmp4Frame.errorCode === Result.ErrorCode.SUCCESS) {
            this._doAppendSegments(fmp4Frame.data);
          }
          else {
            /**
             * 封装Fmp4出错，进行错误处理
             */
            console.error('makeVideoFrame:'+fmp4Frame.errorCode);
            if (this.options.onErrorFun) {
              this.options.onErrorFun(6)
            }
          }
        }
        else {
          /**
           * MSE对象繁忙，进行缓存
           */
          let result = this.fmp4.saveVideoFrame(rtpFrame, rtpFrame.duration);
          if(result !== Result.ErrorCode.SUCCESS) {
            /**
             * 缓存出错，进行错误处理
             */
            console.error('saveVideoFrame:'+result);
          }
        }
        this.startTime = rtpFrame.time;
      }
      else if(
          rtpFrame.media_type === Result.MediaType.AAC || rtpFrame.media_type === Result.MediaType.G711A || rtpFrame.media_type === Result.MediaType.G711U
      ) 
      {
        // console.log('audio time='+rtpFrame.time+',duration='+rtpFrame.duration);
        /**
         * 处理音频数据
         */
        if (this.audioEnabled) {
          if (!this.pcmPlayer){
            this.pcmPlayer = new PCMPlayer(1, 8000);
          }
          if (!this.audioCodec){
            this.audioCodec = new AudioCodec(this.audioOpt);
          }

          if (this.audioRecorder){
            this.recvPackageTimeArr.push(rtpFrame.time);
          }
          this.payloadTypeAudio = payloadType;
          let bret = this.audioCodec.decode(rtpFrame.data, payloadType, rtpFrame.media_type);
          if (bret){
            if (this.firstAudioPlayData && this.options.openAudioSuccess){
              this.options.openAudioSuccess();
              this.firstAudioPlayData = false; 
            }
          } else {
            if (this.options.openAudioFail)
              this.options.openAudioFail('音频解码器打开失败');
          }
        }
        if (this.recordEnabled){
          if (!this.audioRecorder){
            this.audioRecorder = new AudioRecorder(this.recordOpt);
          }
          if (this.audioRecorder && this.audioRecorder.hasMediaStream() && this.firstAudioRecordeData){
            let bret = this.audioRecorder.startRecord();
            if (bret){
              this.firstAudioRecordeData = false;
              if (this.options.openAudioSuccess)
                this.options.openAudioSuccess();
            } else {
              this.audioRecorder = null;
              if (this.options.openAudioFail)
                this.options.openAudioFail('录音设备初始化失败');
            }
          }
        }
      }
      else {
        /**
         * 处理其他数据
         */
      }
    }
    else {

      /**
       * 解析rtp数据出错，进行错误处理
       */
      if (this.options.onErrorFun) {
        this.options.onErrorFun(5)
      }
    }
  }
  _onDecodeDataAudio(pcmFloat32Data, sampleRate, channels) {
    if (this.audioRecorder){
      this.audioRecorder.pushAudioFrameSampleCount(pcmFloat32Data.length*8000/sampleRate);
    }
    if (this.pcmPlayer){
      console.log('onDecodeData2', this.pcmPlayer, channels, sampleRate, pcmFloat32Data)
      this.pcmPlayer.setChannels(channels);
      this.pcmPlayer.setSampleRate(sampleRate);
      this.pcmPlayer.feed(pcmFloat32Data);
    }
  }
  _onEncodeDataAudio(data){

    let timestamp = this.recvPackageTimeArr.shift();

    let payloadType = this.payloadTypeAudio;
    // aac改为g711a
    if (payloadType == 19){
      payloadType = 6;
    }
    let rtpData = this.rtp.makeAudio(data, timestamp, payloadType);

    if(rtpData.errorCode === Result.ErrorCode.SUCCESS) {
      // 音频片段发送给socket
      if (this.websocket && this.websocket.readyState === 1) {
        this.websocket.send(rtpData.data);
      }
    }
  }


  _onRecordDataAudio(pcmPacketData){
    if (!this.audioCodec) return;

    this.audioCodec.encode(pcmPacketData, this.payloadTypeAudio);
  }
  _onDevicePresent(){
    if (this.options.onDevicePresentFunc){
      this.options.onDevicePresentFunc();
    }
  }


  /**
   * 销毁mse
   * @private
   */
  _destroyMSE(){
    console.log('destroyMSE');
    if (this.mediaSource) {
      if (this.mediaSource.readyState === 'open') {
        try {
          this.sourceBuffer.abort();
        } catch (err) {
          console.log(err.message);
        }
      }

      if (this.mediaSource.readyState !== 'closed') {
        this.mediaSource.removeSourceBuffer(this.sourceBuffer);
      }

      if (this.mediaSource.readyState === 'open') {
        this.mediaSource.endOfStream();
      }

      /**
       * 注销sourceBuffer
       */
      if (this.sourceBuffer) {
        if (this.sourceBuffer.readyState !== undefined) {
          this.mediaSource.removeSourceBuffer(this.sourceBuffer);
        }

        this.sourceBuffer = null;
      }

      /**
       * 注销mediasource
       */
      this.mediaSource = null;

      /**
       * 清空其它数据
       */
      clearInterval(this.pendingRemoveRanges);
      this.pendingRemoveRanges = null;
    }

    /**
     * video标签清空src属性
     */
    if (this.mediaElement) {
      this.videoCurrentTime = this.mediaElement.currentTime;
      this.mediaElement.setAttribute('data-currenttime', this.videoCurrentTime);
      console.log('mediaElement', this.mediaElement);
      if (!this.mediaElement.getAttribute('data-video-stop')) {
        this.mediaElement.src = '';
        this.mediaElement.load();
        this.mediaElement.removeAttribute('src');
        this.mediaElement.removeAttribute('data-channel-up');
      }
      this.mediaElement = null;
    }

    if (this.mediaSourceObjectURL) {
      window.URL.revokeObjectURL(this.mediaSourceObjectURL);
      this.mediaSourceObjectURL = null;
    }
  }

  /**
   * 监听messages是否发送数据
   * 8秒无数据推送重新连接
   */
  _monitoringMessage () {
    var that = this;
    this.timeOutMonitoring = setTimeout(function () {
      if (!that.messageState) {
        that.websocket.close();
        this.timeoutNumber++;
        if (this.timeoutNumber < 4) {
          if (that.options.timeoutFun) {
            that.options.timeoutFun(that.options.data, this.timeoutNumber);
          }
        } else {
          this.timeoutNumber = 0;
        }
      };
    }, 8000);
  }

  /**
   * 视频跳转到最新缓存时间点
   */
  _videoUpdateTime() {
    if (this.mediaElement && this.sourceBuffer) {
      if (!this.sourceBuffer.updating) {
        if (this.mediaSource.readyState === 'open') {
          this.mediaElement.currentTime = this.sourceBuffer.buffered.end(0);
        }
      }
    }

    if (this.sourceBuffer) {
      let buffered = this.sourceBuffer.buffered;
      if (buffered.length > 0) {
        let start = buffered.start(0);
        let end = buffered.end(0);
        try {
          this.sourceBuffer.remove(start, end - 10);
        } catch (err) {
          // console.warn(err.message);
        }
      }
    }
  }


  // 关闭socket
  closeSocket (message='') {
    console.log('video socket colose');
    if (this.websocket) {
      this.streamInfo.message = message;
      this.websocket.close();

      this.socketState = false;
      clearTimeout(this.timeOutMonitoring);
      clearInterval(this.pendingRemoveRanges);
      this.pendingRemoveRanges = null;
      this.destroy();
    }
  }

  /**
   * 抓图
   * 使用canvas
   */
  videoScreenshots (canvasId, width, height) {
    /**
     * 创建canvasu节点
     * @type {Element}
     */
    if (this.mediaElement) {
      //创建canvasu节点
      const canvasElement = document.getElementById(canvasId);
      var canvasCtx = canvasElement.getContext('2d');
      //进行抓图
      canvasCtx.drawImage(this.mediaElement, 0, 0, width, height);

      //转换成图像
      var formData = new FormData();
      canvasElement.toBlob(function(blob){
        formData.append('file', blob);
      });
      return formData;
    }
  }

  /**
   * 销毁事件
   * 关闭视频
   */
  destroy () {

    this._destroyMSE();

    document.removeEventListener('visibilitychange', this._visibilitychangeFun.bind(this));


    this.messageState = false;
    this.isVideoPlay = false;
    this.pageFocus = true;
    this.timeOutMonitoring = null;

    /**
     * 清空音频数据
     * @type {Rtp}
     */
    this.rtp = new Rtp();


    if (this.heartbeat) {
      clearInterval(this.heartbeat);
      this.heartbeat = null;
    }

    this.startTime = 0;

    if (this.freeTimeout) {
      clearTimeout(this.freeTimeout);
      this.freeTimeout = null;
    }

    // 销毁音频
    this.closeVideoVoice();

    this.isPFrame = 0;
    this.videoCurrentTime = 0;
  }

  /**
   * 获取视频流量值
   */
  getVideoTraffic () {
    return this.rtp.getFlow();
  }

  /**
   * 开启声音
   */
  openVideoVoice() {
    this.firstAudioData = true;
    this.audioEnabled = true;
  }

  /**
   * 关闭声音
   */
  closeVideoVoice() {
    if (this.audioCodec !== null){
      this.audioCodec.destroy();
      this.audioCodec = null;
    }
    if (this.pcmPlayer !== null) {
      this.pcmPlayer.close();
      this.pcmPlayer = null;
    }
    this.audioEnabled = false;
  }

  /**
   * 设置音频的播放声音
   */
  setAudioVoice(index) {
    if (this.pcmPlayer !== null) {
      this.pcmPlayer.setVolume(index);
    }
  }

  /**
   * 空闲超时断开
   */
  freeTimeoutClose(time, callBack) {
    this.closeFreeTimeout();
    var that = this;
    if (that.websocket) {
      that.freeTimeout = setTimeout(() => {
        if (callBack && typeof callBack === 'function') {
          var id = that.mediaElement.getAttribute('vehicle-id');
          var channelType = that.mediaElement.getAttribute('channel-type');
          var channelNum = that.mediaElement.getAttribute('channel-num');
          callBack(id, channelNum, channelType);
        }
        that.closeSocket();
      }, time);
    }
  }

  /**
   * 关闭空闲超时
   */
  closeFreeTimeout() {
    if (this.isOpenFreeTime()) {
      clearTimeout(this.freeTimeout);
      this.freeTimeout = null;
    }
  }

  /**
   * 判断是否触发了空闲超时
   */
  isOpenFreeTime() {
    return this.freeTimeout !== null;
  }

  /**
   * 获取当前的播放时间，相对与开始播放时的时间(单位:s)
   */
  currentTime() {
    if (this.mediaElement){
      return this.mediaElement.currentTime;
    } else {
      return 0;
    }
  }
}

RTPMediaPlayer.arr = [];